The following article was originally taken from the usenet group rec.games.programmer.
Article 1:
I've had a "look" at Jazz (*grin*) and a friend also had a look. We've come to the conclusion that it modifies the OFFSET register to give a wider logical screen. It set it to something like 336 pixels across, although you still only see 320. The point behind this is that you can then use the Start Address register and PEL panning to get sideways scrolling, and the Start Address register to get vertical scrolling.
Article 2:
This text describes a method for smooth multidirectional scrolling using 3 buffers in vga memory. To my knowledge, Jazz Jackrabbit uses a similar scheme, but still not having seen the game I would not know.
I thought up this method by myself a year back in the summer, when I only begun PC programming (in assembly) and wanted to prove to myself that smooth scrolling is not as hard task as people seem to cast it out to be. It turned out it was actually a lot easier than on the Amiga which I originally had been programming in, and came up with the following solution.
------------------------------------------------------------------------------ ---- Document for 3-buffer Mode X multidir. scroll (C) 1995 Jouni Mannonen --- --- Distributed with permission from author --- ------------------------------------------------------------------------------
VGA RAM, starting at 0A000:0000h address window.
,------. |screen| | 1 | --. +------+ | visible screen page \ |screen| | \__ ACTIVE pages, flipped between | 2 | --+ / in double buffering +------+ | hidden screen page / |screen| | | 3 | --' `------'
In this scheme, 3 full copies of the screen are kept in the vga ram at one time, across which the 2 visible screens "slide" during scroll.
Scrolling up/down is simply done by shifting the visible pages up and down across the physical vga ram, 320 bytes at a time (assuming a screen 320 pixels wide). At the same time the visible page start address is incremented/decremented with 320, and data to both top and bottom of the active pages is drawn to constantly keep 3 full copies of the playfield in vga memory.
Scrolling left/right is handled by shifting these screens 1 pixel forward and backward in video ram, each screen left shifting the whole set forward by 320 bytes. Thus, for a total playfield of 20 screens in width, you you need to allocate an extra 20*320 = 6400 bytes of memory. Note that again you have to update the new graphics data to the left/right of all the 3 screens.
Double buffering is done by flipping between the visible and hidden page, whenever the active pages reach the top or bottom of the 3 screens, they are flipped one screen back thus give a virtually infinite up/down scrolling region.
Should there be need to draw data in 16 pixel blocks, extra 16 bytes of width and height for each screen are to be allocated.
When there are sprites to be drawn, they are done directly over the hidden active page, and have to be removed in the next pass to not cumulatively mess up the playfield image.